package com.iwhalecloud.uncc.service.impl;

import com.iwhalecloud.uncc.common.ArchiverConstant;
import com.iwhalecloud.uncc.common.ArchiverThreadLocal;
import com.iwhalecloud.uncc.common.SysConstant;
import com.iwhalecloud.uncc.dao.ArchiverDao;
import com.iwhalecloud.uncc.db.DatasourceContextHolder;
import com.iwhalecloud.uncc.domain.InsCollectServiceArchiverMsg;
import com.iwhalecloud.uncc.exception.ArchiverException;
import com.iwhalecloud.uncc.model.*;
import com.iwhalecloud.uncc.properties.mq.ArchiverTopicProperties;
import com.iwhalecloud.uncc.service.ArchiverService;
import com.iwhalecloud.uncc.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zq
 * @date 2021/10/20 11:37
 * @description
 */
@Slf4j

@Service("insCollectServiceArchiverService")
public class InsCollectServiceArchiverServiceImpl implements ArchiverService<InsCollectService> {

    @Autowired
    private ArchiverDao insCollectServiceArchiverDao;
    @Autowired
    private ArchiverDao insAlarmMsgArchiverDao;
    @Autowired
    private ArchiverDao insServiceActiveLogArchiverDao;
    @Autowired
    private ArchiverDao moniBrStatInfoArchiverDao;
    @Autowired
    private ArchiverDao moniItStatInfoArchiverDao;
    @Autowired
    private ArchiverDao scalServiceExpanseLogArchiverDao;
    @Autowired
    private ArchiverDao insEventRecordArchiverDao;
    @Autowired
    private ArchiverTopicProperties archiverTopicProperties;
    @Autowired
    private DataSourceUtil dataSourceUtil;

    @Async("taskExecutor")
    @Override
    public void archive(String partitionCode) {
        DatasourceContextHolder.setDs(partitionCode);
        this.doArchive();
        DatasourceContextHolder.setDs(SysConstant.DB_DEFAULT_PARTITION);
    }

    private void doArchive()  {
        long s = System.currentTimeMillis();
        if (log.isInfoEnabled()) {
            log.info(Thread.currentThread().getName() + "执行归档 "
                    + DatasourceContextHolder.getDs() + "数据库 InsCollectService 关联数据任务 ...");
        }

        //查所有的InsCollectService
        List<InsCollectService> list = insCollectServiceArchiverDao.queryList(null);

        if(list == null){
            if (log.isInfoEnabled()) {
                log.info("此次归档任务insCollectServiceList = NULL");
                log.info(Thread.currentThread().getName()
                        + "完成任务:NULL 耗时:" + ((System.currentTimeMillis() - s) / 1000) + "s");
            }
            return;
        }

        DivideUtil.divideSend(this,list);

        if (log.isInfoEnabled()) {
            log.info(Thread.currentThread().getName() + "完成归档发送任务 耗时:"
                    + ((System.currentTimeMillis() - s) / 1000) + "s");
        }
    }

    @Override
    public void packMsg(List<InsCollectService> list) {

        List<Long> collServiceIds = new ArrayList<>();
        list.forEach(i->collServiceIds.add(i.getCollServiceId()));

        List<InsAlarmMsg>  insAlarmMsgList = CheckUtil.batchQuery(insAlarmMsgArchiverDao,collServiceIds);
        List<InsServiceActiveLog>  insServiceActiveLogList = CheckUtil.batchQuery(insServiceActiveLogArchiverDao,collServiceIds);
        List<MoniBrStatInfo>  moniBrStatInfoList = CheckUtil.batchQuery(moniBrStatInfoArchiverDao,collServiceIds);
        List<MoniItStatInfo>  moniItStatInfoList = CheckUtil.batchQuery(moniItStatInfoArchiverDao,collServiceIds);
        List<ScalServiceExpanseLog> scalServiceExpanseLogList = CheckUtil.batchQuery(scalServiceExpanseLogArchiverDao,collServiceIds);
        List<InsEventRecord> insEventRecordList = CheckUtil.batchQuery(insEventRecordArchiverDao,collServiceIds);

        List<Integer> abstractIds = new ArrayList<>();
        list.forEach(i->abstractIds.add(i.getAbstractId()));
        insEventRecordList = CheckUtil.dealInsEventRecord(insEventRecordList,
                CheckUtil.batchQuery(insEventRecordArchiverDao,abstractIds));
        insEventRecordList = (insEventRecordList == null) ? null
                : insEventRecordList.stream().distinct().collect(Collectors.toList());

        if(insAlarmMsgList == null && insServiceActiveLogList == null  && moniBrStatInfoList == null
                && moniItStatInfoList == null  && scalServiceExpanseLogList == null  && insEventRecordList == null ){
            return;
        }

        //修改 Flag
        CheckUtil.batchUpdateArchiving(insAlarmMsgArchiverDao,insAlarmMsgList);
        CheckUtil.batchUpdateArchiving(insServiceActiveLogArchiverDao,insServiceActiveLogList);
        CheckUtil.batchUpdateArchiving(moniBrStatInfoArchiverDao,moniBrStatInfoList);
        CheckUtil.batchUpdateArchiving(moniItStatInfoArchiverDao,moniBrStatInfoList);
        CheckUtil.batchUpdateArchiving(scalServiceExpanseLogArchiverDao,scalServiceExpanseLogList);
        CheckUtil.batchUpdateArchiving(insEventRecordArchiverDao,insEventRecordList);

        //组装Msg
        InsCollectServiceArchiverMsg insCollectServiceArchiverMsg = new InsCollectServiceArchiverMsg();
        insCollectServiceArchiverMsg.setIsDeleteOnline(ArchiverThreadLocal.getArchiveParam().getIsDeleteOnline());
        insCollectServiceArchiverMsg.setPartitionCode(DatasourceContextHolder.getDs());
        insCollectServiceArchiverMsg.setInsCollectServiceList(list);
        insCollectServiceArchiverMsg.setInsAlarmMsgList(insAlarmMsgList);
        insCollectServiceArchiverMsg.setInsServiceActiveLogList(insServiceActiveLogList);
        insCollectServiceArchiverMsg.setMoniBrStatInfoList(moniBrStatInfoList);
        insCollectServiceArchiverMsg.setMoniItStatInfoList(moniItStatInfoList);
        insCollectServiceArchiverMsg.setScalServiceExpanseLogList(scalServiceExpanseLogList);
        insCollectServiceArchiverMsg.setInsEventRecordList(insEventRecordList);


        //发送MQ
        try{
            sendMsg(insCollectServiceArchiverMsg);
        }catch (ArchiverException a){
            if (log.isInfoEnabled()) {
                log.info(Thread.currentThread().getName() + a.getErrorMessage());
            }
            //重置 Flag
            CheckUtil.batchResetOnline(insAlarmMsgArchiverDao,insAlarmMsgList);
            CheckUtil.batchResetOnline(insServiceActiveLogArchiverDao,insServiceActiveLogList);
            CheckUtil.batchResetOnline(moniBrStatInfoArchiverDao,moniBrStatInfoList);
            CheckUtil.batchResetOnline(moniItStatInfoArchiverDao,moniBrStatInfoList);
            CheckUtil.batchResetOnline(scalServiceExpanseLogArchiverDao,scalServiceExpanseLogList);
            CheckUtil.batchResetOnline(insEventRecordArchiverDao,insEventRecordList);

            a.printStackTrace();
        }
    }

    private void sendMsg(InsCollectServiceArchiverMsg msg) throws ArchiverException {
        String key = ArchiverConstant.PREFIX_INS_COLLECT_SERVICE + msg.getInsCollectServiceList().get(0).getCollServiceId();
        String topic = archiverTopicProperties.getInsCollectServiceArchiverTopic();
        ArchiverUtil.sendMsg(topic,key,msg);
    }
}
